import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // 轨道控制
import { GUI } from 'lil-gui';
import doorTextureUrl from '@/assets/texture/door/color.jpg';
import doorAlphaTextureUrl from '@/assets/texture/door/alpha.jpg';
import doorAOMap from '@/assets/texture/door/ambientOcclusion.jpg';
import doorHeightTextureUrl from '@/assets/texture/door/height.jpg';
import normalTextureUrl from '@/assets/texture/door/normal.jpg';
import roughnessTextureUrl from '@/assets/texture/door/roughness.jpg';

export default function index() {
  const mountRef = useRef(null);
  const gui = new GUI();
  useEffect(() => {
    // 场景
    const scene = new THREE.Scene();
    // 相机
    const camera = new THREE.PerspectiveCamera(75);
    camera.position.set(0, 0, 20);
    scene.add(camera);
    // 光源
    const ambientLight = new THREE.AmbientLight(0xb9d5ff, 0.2);
    const moonLight = new THREE.DirectionalLight(0xb9d5ff, 0.2);
    moonLight.position.set(4, 5, -2);
    moonLight.castShadow = true; // 开启阴影
    scene.add(ambientLight, moonLight);
    // 门光
    const doorLight = new THREE.PointLight(0xff7d46, 4.7, 7);
    doorLight.position.set(0, 0.21, 4.75);
    scene.add(doorLight);
    gui.add(doorLight.position, 'x').min(-5).max(5).step(0.01);
    gui.add(doorLight.position, 'y').min(-5).max(5).step(0.01);
    gui.add(doorLight.position, 'z').min(-5).max(5).step(0.01);

    // fog 雾 颜色、雾气开始渲染距离相机的位置、雾气结束渲染距离相机的位置
    const fog = new THREE.Fog(0x262837, 3, 30);
    scene.fog = fog;

    /* 纹理 */
    const textureLoader = new THREE.TextureLoader();
    const doorTexture = textureLoader.load(doorTextureUrl);
    const doorAlphaTexture = textureLoader.load(doorAlphaTextureUrl);
    const doorAmbientOcclusionTexture = textureLoader.load(doorAOMap);
    const doorHeightTexture = textureLoader.load(doorHeightTextureUrl);
    const doorNormalTexture = textureLoader.load(normalTextureUrl);
    const doorRoughnessTexture = textureLoader.load(roughnessTextureUrl);
    /**
     * 创建house group
     */
    const houseGroup = new THREE.Group();
    houseGroup.rotation.x = Math.PI * 0.25;
    scene.add(houseGroup);

    // walls
    const walls = new THREE.Mesh(
      new THREE.BoxGeometry(4, 2.5, 4),
      new THREE.MeshStandardMaterial({ color: 0xac8e82 })
    );
    walls.position.y = 1.25;
    houseGroup.add(walls);
    // door
    const door = new THREE.Mesh(
      new THREE.PlaneGeometry(2, 2),
      new THREE.MeshStandardMaterial({
        map: doorTexture,
        alphaMap: doorAlphaTexture, // 透明度贴图
        transparent: true,
        aoMap: doorAmbientOcclusionTexture, // 环境遮挡贴图
        displacementMap: doorHeightTexture, // 位移贴图
        displacementScale: 0.1, // 位移贴图的强度
        normalMap: doorNormalTexture, // 法线贴图
        roughnessMap: doorRoughnessTexture, // 粗糙度贴图
      })
    );
    door.position.z = 2 + 0.01; // 防止和wall重叠
    door.position.y = 1;
    houseGroup.add(door);
    // roof
    const roof = new THREE.Mesh(
      new THREE.ConeGeometry(3.5, 1, 4),
      new THREE.MeshStandardMaterial({ color: 0xb35f45 })
    );

    roof.rotation.y = Math.PI * 0.25;
    roof.position.y = 2.5 + 0.5; // 锥形的中心在高的中间;
    houseGroup.add(roof);
    // bushes
    const bushGeometry = new THREE.SphereGeometry(1, 16, 16);
    const bushMaterial = new THREE.MeshStandardMaterial({ color: 0x89c854 });
    const bush1 = new THREE.Mesh(bushGeometry, bushMaterial);
    bush1.scale.set(0.5, 0.5, 0.5);
    bush1.position.set(0.8, 0.2, 2.2);
    const bush2 = new THREE.Mesh(bushGeometry, bushMaterial);
    bush2.scale.set(0.25, 0.25, 0.25);
    bush2.position.set(1.4, 0.1, 2.1);
    const bush3 = new THREE.Mesh(bushGeometry, bushMaterial);
    bush3.scale.set(0.4, 0.4, 0.4);
    bush3.position.set(-1, 0.1, 2.2);
    const bush4 = new THREE.Mesh(bushGeometry, bushMaterial);
    bush4.scale.set(0.15, 0.15, 0.15);
    bush4.position.set(-1.3, 0.05, 2.6);
    const bush5 = new THREE.Mesh(bushGeometry, bushMaterial);
    bush5.scale.set(0.35, 0.3, 0.3);
    bush5.position.set(-1.7, 0.1, 2.3);
    houseGroup.add(bush1, bush2, bush3, bush4, bush5);

    /* grave group */
    const graveGroup = new THREE.Group();
    graveGroup.rotation.x = Math.PI * 0.25;
    scene.add(graveGroup);
    const graveGeometry = new THREE.BoxGeometry(0.6, 0.8, 0.2);
    const graveMaterial = new THREE.MeshStandardMaterial({ color: 0xb2b6b9 });
    for (let i = 0; i < 50; i++) {
      const angle = Math.random() * Math.PI * 2; //  [0, 2π) 弧度
      const radius = 3.5 + Math.random() * 6; // [3.5,9.5) 的随机半径值 ,距离中心3.5-9.5之间
      const x = Math.sin(angle) * radius; // x = r × sin(θ)
      const z = Math.cos(angle) * radius; // z = r × cos(θ)
      const grave = new THREE.Mesh(graveGeometry, graveMaterial);
      grave.position.set(x, 0.4, z);
      grave.rotation.y = (Math.random() - 0.5) * 0.5;
      graveGroup.add(grave);
    }
    // floor
    const floor = new THREE.Mesh(
      new THREE.PlaneGeometry(20, 20),
      new THREE.MeshStandardMaterial({ color: 0xa9c388 })
    );
    floor.rotation.x = -Math.PI * 0.25;
    scene.add(floor);
    // 渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    mountRef.current.appendChild(renderer.domElement); // 将渲染器的DOM元素添加到React组件
    renderer.setClearColor(0x262837); // 设置场景的背景颜色与雾气一直 模糊边缘
    renderer.render(scene, camera);

    /**
     * 阴影
     */
    renderer.shadowMap.enabled = true; // 开启阴影
    walls.castShadow = true; // 开启投射阴影
    floor.receiveShadow = true; // 接收阴影
    // 轨道控制
    const controls = new OrbitControls(camera, renderer.domElement);

    // 动画
    const animate = () => {
      controls.update();
      renderer.render(scene, camera);
      window.requestAnimationFrame(animate); // 会在下一帧调用此函数
    };
    animate();
  }, []);

  return (
    <div
      ref={mountRef}
      style={{ width: '100%', height: '100vh' }}
    />
  );
}
